package com.czk.gulimall.service.common.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/12/24 17:01
 */
@Slf4j
@Aspect
@Component
public class ControllerAop {
    @Pointcut(value = "execution(* com.czk.gulimall.*.controller..*Controller.*(..))")
    public void aopPoint() {

    }

    @Around("aopPoint()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 当前时间
        Long start = System.currentTimeMillis();
        // 拿到方法
        Method method = getMethod(joinPoint);
        // 执行方法
        try {
            return joinPoint.proceed();
        } finally {
            log.info("监控----by aop");
            log.info("监控方法----" + method.getDeclaringClass() + "=======" + method.getName());
            Parameter[] parameters = method.getParameters();
            // 拿到所有的参数值
            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < parameters.length; i++) {
                Parameter parameter = parameters[i];
                log.info("参数名称是{},类型是{},内容是{}", parameter.getName(), parameter.getType(), args[i]);
            }
            log.info("监控耗时----" + (System.currentTimeMillis() - start));
            log.info("监控结束-----");
        }
    }

    private Method getMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        Signature signature = joinPoint.getSignature();
        // 拿到方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        // 返回方法
        return joinPoint.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }
}
